package com.googlecode.ocl2sqlcompiler;

import java_cup.runtime.Symbol;
import java.math.BigDecimal;

@SuppressWarnings("unused")


%%

%class OCLScanner
%public
%debug
%unicode
%cupsym OCLSymbols
%cup
%char
%line
%column

%{

  private Symbol createSymbol(int type) {
    return new Symbol(type, yyline, yycolumn);
  }
  
  private <T> Symbol createSymbol(int type, OCLType oclType, T value) {
    return new Symbol(type, yyline, yycolumn, new OCLSemanticObject<T>(oclType, value));
  }
  
%}


letter					= [a-zA-Z]
digit 					= [0-9]
underline 				= _
hash 					= #
colon 					= ":"
double_colon			= "::"
dot 					= "."
arrow					= "->"
comma					= ","
semicolon				= ";"
open_parentheses		= "("
close_parentheses		= ")"
open_bracket			= "{"
close_bracket			= "}"
apostrophe				= "'"
pipe					= "|"

equals					= "="
less_than				= "<"
greater_than			= ">"
less_than_or_equals 	= "<="
greater_than_or_equals 	= ">="
different				= "<>"

plus					= "+"
minus					= "-"
times					= "*"
div						= "/"

context 				= "context"
body	 				= "body"
init 					= "init"
def						= "def"
self					= "self"
and						= "and"
or						= "or"
xor						= "xor"
not						= "not"
if						= "if"
then					= "then"
else 					= "else"
endif					= "endif"
implies					= "implies"

identifier 				= {letter}({letter}|{digit}|{underline}|{hash})*
integer_value			= {digit}+
real_value				= {integer_value}({dot}{integer_value})?
true 					= "true"
false 					= "false"
boolean_value 			= {true}|{false}
string_value			= {apostrophe}~{apostrophe}

line_break 				= \r|\n|\r\n
white_space				= {line_break} | [ \t\f]

embedded_comment		= {div}{times}~{times}{div}
line_comment			= {minus}{minus}~{line_break}


%%

{context} 					{ return createSymbol(OCLSymbols.CONTEXT); }
{init} 						{ return createSymbol(OCLSymbols.INIT); }
{body}						{ return createSymbol(OCLSymbols.BODY); }
{def}						{ return createSymbol(OCLSymbols.DEF); }
{self}						{ return createSymbol(OCLSymbols.SELF); }
{and}						{ return createSymbol(OCLSymbols.AND); }
{or}						{ return createSymbol(OCLSymbols.OR); }
{xor}						{ return createSymbol(OCLSymbols.XOR); }
{not}						{ return createSymbol(OCLSymbols.NOT); }
{if}						{ return createSymbol(OCLSymbols.IF); }
{then}						{ return createSymbol(OCLSymbols.THEN); }
{else}						{ return createSymbol(OCLSymbols.ELSE); }
{endif}						{ return createSymbol(OCLSymbols.ENDIF); }
{implies}					{ return createSymbol(OCLSymbols.IMPLIES); }

{double_colon}				{ return createSymbol(OCLSymbols.DOUBLE_COLON); }
{colon}						{ return createSymbol(OCLSymbols.COLON); }
{dot}						{ return createSymbol(OCLSymbols.DOT); }
{arrow}						{ return createSymbol(OCLSymbols.ARROW); }
{comma}						{ return createSymbol(OCLSymbols.COMMA); }
{semicolon}					{ return createSymbol(OCLSymbols.SEMICOLON); }
{open_parentheses}			{ return createSymbol(OCLSymbols.OPEN_PARENTHESES); }
{close_parentheses}			{ return createSymbol(OCLSymbols.CLOSE_PARENTHESES); }
{open_bracket}				{ return createSymbol(OCLSymbols.OPEN_BRACKET); }
{close_bracket}				{ return createSymbol(OCLSymbols.CLOSE_BRACKET); }
{pipe}						{ return createSymbol(OCLSymbols.PIPE); }
{less_than_or_equals}		{ return createSymbol(OCLSymbols.LESS_THAN_OR_EQUALS); }
{greater_than_or_equals}	{ return createSymbol(OCLSymbols.GREATER_THAN_OR_EQUALS); }
{different}					{ return createSymbol(OCLSymbols.DIFFERENT); }
{equals}					{ return createSymbol(OCLSymbols.EQUALS); }
{less_than}					{ return createSymbol(OCLSymbols.LESS_THAN); }
{greater_than}				{ return createSymbol(OCLSymbols.GREATER_THAN); }
{plus}						{ return createSymbol(OCLSymbols.PLUS); }
{minus}						{ return createSymbol(OCLSymbols.MINUS); }
{times}						{ return createSymbol(OCLSymbols.TIMES); }
{div}						{ return createSymbol(OCLSymbols.DIV); }

{boolean_value}				{ return createSymbol(OCLSymbols.BOOLEAN_VALUE, OCLType.BOOLEAN, OCLBoolean.valueOf(yytext().toUpperCase())); }
{identifier}				{ return createSymbol(OCLSymbols.IDENTIFIER, OCLType.MODEL, yytext()); }
{integer_value}				{ return createSymbol(OCLSymbols.INTEGER_VALUE, OCLType.INTEGER, new OCLNumber(yytext())); }
{real_value}				{ return createSymbol(OCLSymbols.REAL_VALUE, OCLType.REAL, new OCLNumber(yytext())); }
{string_value}				{ return createSymbol(OCLSymbols.STRING_VALUE, OCLType.STRING, yytext()); }

{line_break}				|
{white_space}				|
{embedded_comment}			|
{line_comment}				{ }
				
